

\section{偏微分方程 }\label{ux504fux5faeux5206ux65b9ux7a0b}

\textbf{\emph{TensorFlow}}
不仅仅是用来机器学习，它更可以用来模拟仿真。在这里，我们将通过模拟仿真几滴落入一块方形水池的雨点的例子，来引导您如何使用
\textbf{\emph{TensorFlow}} 中的偏微分方程来模拟仿真的基本使用方法。

\begin{quote}
注：本教程最初是准备做为一个 \textbf{IPython} 的手册。
\textgreater{}译者注:关于偏微分方程的相关知识，译者推荐读者查看
\href{http://open.163.com/}{\textbf{网易公开课}}
上的\href{http://open.163.com/special/opencourse/multivariable.html}{\textbf{《麻省理工学院公开课：多变量微积分》}}课程。
\end{quote}

\subsection{基本设置 }\label{ux57faux672cux8bbeux7f6e}

首先,我们需要导入一些必要的引用。

\begin{Shaded}
\begin{Highlighting}[]
\CommentTok{#导入模拟仿真需要的库}
\ImportTok{import} \NormalTok{tensorflow }\ImportTok{as} \NormalTok{tf}
\ImportTok{import} \NormalTok{numpy }\ImportTok{as} \NormalTok{np}

\CommentTok{#导入可视化需要的库}
\ImportTok{import} \NormalTok{PIL.Image}
\ImportTok{from} \NormalTok{cStringIO }\ImportTok{import} \NormalTok{StringIO}
\ImportTok{from} \NormalTok{IPython.display }\ImportTok{import} \NormalTok{clear_output, Image, display}
\end{Highlighting}
\end{Shaded}

然后，我们还需要一个用于表示池塘表面状态的函数。

\begin{Shaded}
\begin{Highlighting}[]
\KeywordTok{def} \NormalTok{DisplayArray(a, fmt}\OperatorTok{=}\StringTok{'jpeg'}\NormalTok{, rng}\OperatorTok{=}\NormalTok{[}\DecValTok{0}\NormalTok{,}\DecValTok{1}\NormalTok{]):}
  \CommentTok{"""Display an array as a picture."""}
  \NormalTok{a }\OperatorTok{=} \NormalTok{(a }\OperatorTok{-} \NormalTok{rng[}\DecValTok{0}\NormalTok{])}\OperatorTok{/}\BuiltInTok{float}\NormalTok{(rng[}\DecValTok{1}\NormalTok{] }\OperatorTok{-} \NormalTok{rng[}\DecValTok{0}\NormalTok{])}\OperatorTok{*}\DecValTok{255}
  \NormalTok{a }\OperatorTok{=} \NormalTok{np.uint8(np.clip(a, }\DecValTok{0}\NormalTok{, }\DecValTok{255}\NormalTok{))}
  \NormalTok{f }\OperatorTok{=} \NormalTok{StringIO()}
  \NormalTok{PIL.Image.fromarray(a).save(f, fmt)}
  \NormalTok{display(Image(data}\OperatorTok{=}\NormalTok{f.getvalue()))}
\end{Highlighting}
\end{Shaded}

最后，为了方便演示，这里我们需要打开一个 \textbf{\emph{TensorFlow}}
的交互会话（interactive
session）。当然为了以后能方便调用，我们可以把相关代码写到一个可以执行的\textbf{\emph{Python}}文件中。

\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{sess }\OperatorTok{=} \NormalTok{tf.InteractiveSession()}
\end{Highlighting}
\end{Shaded}

\subsection{定义计算函数 }\label{ux5b9aux4e49ux8ba1ux7b97ux51fdux6570}

\begin{Shaded}
\begin{Highlighting}[]
\KeywordTok{def} \NormalTok{make_kernel(a):}
  \CommentTok{"""Transform a 2D array into a convolution kernel"""}
  \NormalTok{a }\OperatorTok{=} \NormalTok{np.asarray(a)}
  \NormalTok{a }\OperatorTok{=} \NormalTok{a.reshape(}\BuiltInTok{list}\NormalTok{(a.shape) }\OperatorTok{+} \NormalTok{[}\DecValTok{1}\NormalTok{,}\DecValTok{1}\NormalTok{])}
  \ControlFlowTok{return} \NormalTok{tf.constant(a, dtype}\OperatorTok{=}\DecValTok{1}\NormalTok{)}

\KeywordTok{def} \NormalTok{simple_conv(x, k):}
  \CommentTok{"""A simplified 2D convolution operation"""}
  \NormalTok{x }\OperatorTok{=} \NormalTok{tf.expand_dims(tf.expand_dims(x, }\DecValTok{0}\NormalTok{), }\OperatorTok{-}\DecValTok{1}\NormalTok{)}
  \NormalTok{y }\OperatorTok{=} \NormalTok{tf.nn.depthwise_conv2d(x, k, [}\DecValTok{1}\NormalTok{, }\DecValTok{1}\NormalTok{, }\DecValTok{1}\NormalTok{, }\DecValTok{1}\NormalTok{], padding}\OperatorTok{=}\StringTok{'SAME'}\NormalTok{)}
  \ControlFlowTok{return} \NormalTok{y[}\DecValTok{0}\NormalTok{, :, :, }\DecValTok{0}\NormalTok{]}

\KeywordTok{def} \NormalTok{laplace(x):}
  \CommentTok{"""Compute the 2D laplacian of an array"""}
  \NormalTok{laplace_k }\OperatorTok{=} \NormalTok{make_kernel([[}\FloatTok{0.5}\NormalTok{, }\FloatTok{1.0}\NormalTok{, }\FloatTok{0.5}\NormalTok{],}
                           \NormalTok{[}\FloatTok{1.0}\NormalTok{, }\OperatorTok{-}\DecValTok{6}\NormalTok{., }\FloatTok{1.0}\NormalTok{],}
                           \NormalTok{[}\FloatTok{0.5}\NormalTok{, }\FloatTok{1.0}\NormalTok{, }\FloatTok{0.5}\NormalTok{]])}
  \ControlFlowTok{return} \NormalTok{simple_conv(x, laplace_k)}
\end{Highlighting}
\end{Shaded}

\subsection{定义偏微分方程
}\label{ux5b9aux4e49ux504fux5faeux5206ux65b9ux7a0b}

首先,我们需要创建一个完美的 500 × 500
的正方形池塘,就像是我们在现实中找到的一样。

\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{N }\OperatorTok{=} \DecValTok{500}
\end{Highlighting}
\end{Shaded}

然后，我们需要创建了一个池塘和几滴将要坠入池塘的雨滴。

\begin{Shaded}
\begin{Highlighting}[]
\CommentTok{# Initial Conditions -- some rain drops hit a pond}

\CommentTok{# Set everything to zero}
\NormalTok{u_init }\OperatorTok{=} \NormalTok{np.zeros([N, N], dtype}\OperatorTok{=}\StringTok{"float32"}\NormalTok{)}
\NormalTok{ut_init }\OperatorTok{=} \NormalTok{np.zeros([N, N], dtype}\OperatorTok{=}\StringTok{"float32"}\NormalTok{)}

\CommentTok{# Some rain drops hit a pond at random points}
\ControlFlowTok{for} \NormalTok{n }\OperatorTok{in} \BuiltInTok{range}\NormalTok{(}\DecValTok{40}\NormalTok{):}
  \NormalTok{a,b }\OperatorTok{=} \NormalTok{np.random.randint(}\DecValTok{0}\NormalTok{, N, }\DecValTok{2}\NormalTok{)}
  \NormalTok{u_init[a,b] }\OperatorTok{=} \NormalTok{np.random.uniform()}

\NormalTok{DisplayArray(u_init, rng}\OperatorTok{=}\NormalTok{[}\OperatorTok{-}\FloatTok{0.1}\NormalTok{, }\FloatTok{0.1}\NormalTok{])}
\end{Highlighting}
\end{Shaded}

\begin{figure}[htbp]
\centering
\includegraphics{../images/pde_output_1.jpg}
\caption{jpeg}
\end{figure}

现在，让我们来指定该微分方程的一些详细参数。

\begin{Shaded}
\begin{Highlighting}[]
\CommentTok{# Parameters:}
\CommentTok{# eps -- time resolution}
\CommentTok{# damping -- wave damping}
\NormalTok{eps }\OperatorTok{=} \NormalTok{tf.placeholder(tf.float32, shape}\OperatorTok{=}\NormalTok{())}
\NormalTok{damping }\OperatorTok{=} \NormalTok{tf.placeholder(tf.float32, shape}\OperatorTok{=}\NormalTok{())}

\CommentTok{# Create variables for simulation state}
\NormalTok{U  }\OperatorTok{=} \NormalTok{tf.Variable(u_init)}
\NormalTok{Ut }\OperatorTok{=} \NormalTok{tf.Variable(ut_init)}

\CommentTok{# Discretized PDE update rules}
\NormalTok{U_ }\OperatorTok{=} \NormalTok{U }\OperatorTok{+} \NormalTok{eps }\OperatorTok{*} \NormalTok{Ut}
\NormalTok{Ut_ }\OperatorTok{=} \NormalTok{Ut }\OperatorTok{+} \NormalTok{eps }\OperatorTok{*} \NormalTok{(laplace(U) }\OperatorTok{-} \NormalTok{damping }\OperatorTok{*} \NormalTok{Ut)}

\CommentTok{# Operation to update the state}
\NormalTok{step }\OperatorTok{=} \NormalTok{tf.group(}
  \NormalTok{U.assign(U_),}
  \NormalTok{Ut.assign(Ut_))}
\end{Highlighting}
\end{Shaded}

\subsection{开始仿真 }\label{ux5f00ux59cbux4effux771f}

为了能看清仿真效果，我们可以用一个简单的 \textbf{for}
循环来远行我们的仿真程序。

\begin{Shaded}
\begin{Highlighting}[]
\CommentTok{# Initialize state to initial conditions}
\NormalTok{tf.initialize_all_variables().run()}

\CommentTok{# Run 1000 steps of PDE}
\ControlFlowTok{for} \NormalTok{i }\OperatorTok{in} \BuiltInTok{range}\NormalTok{(}\DecValTok{1000}\NormalTok{):}
  \CommentTok{# Step simulation}
  \NormalTok{step.run(\{eps: }\FloatTok{0.03}\NormalTok{, damping: }\FloatTok{0.04}\NormalTok{\})}
  \CommentTok{# Visualize every 50 steps}
  \ControlFlowTok{if} \NormalTok{i }\OperatorTok{%} \DecValTok{50} \OperatorTok{==} \DecValTok{0}\NormalTok{:}
    \NormalTok{clear_output()}
    \NormalTok{DisplayArray(U.}\BuiltInTok{eval}\NormalTok{(), rng}\OperatorTok{=}\NormalTok{[}\OperatorTok{-}\FloatTok{0.1}\NormalTok{, }\FloatTok{0.1}\NormalTok{])}
\end{Highlighting}
\end{Shaded}

\begin{figure}[htbp]
\centering
\includegraphics{../images/pde_output_2.jpg}
\caption{jpeg}
\end{figure}

看！！ 雨点落在池塘中,和现实中一样的泛起了涟漪。

\begin{quote}
原文链接:\url{http://tensorflow.org/tutorials/pdes/index.md}
翻译:{[}@wangaicc{]}(https://github.com/wangaicc)
校对:{[}@tensorfly{]}(https://github.com/tensorfly)
\end{quote}